import { throttle } from "../utils/throttle";
import { ProgressLocation, Uri, window } from "vscode";
import { interpretSolution, InterpretSolutionArgs } from "../apis/interpret-solution";
import { languageService } from "../services/LanguageService";
import { languagesMapLeetCodeStr } from "../common/Languages";
import { interpretCheck } from "../apis/interpret-check";
import { wait } from "../utils/wait";
import { leetCodeOutputChannel } from "../output/QuestionOutputChannel";

/**
 * 执行测试
 */
export const testQuestion = throttle(async (uri: Uri) => {
    return window.withProgress({location: ProgressLocation.Notification}, async p => {
        p.report({message: "执行测试用例"});
        const languages = languageService.getLanguagesByFsPath(uri.fsPath);
        if (!languages) {
            return Promise.reject("获取文件语言失败");
        }
        return languageService.getTestOrSubmitQuestionData(languages).then(value => {
            const {titleSlug, id, judgeType, testCase, code} = value;
            return interpretSolution(new InterpretSolutionArgs(
                titleSlug,
                id,
                languagesMapLeetCodeStr.get(languages)!!,
                code,
                testCase,
                judgeType
            )).then(check);
        });
    });
}, 10000, (value) => {
    if (value[1]) {
        window.showInformationMessage("思考10秒之后再测试吧", {});
    }
});

const check = async (value: { interpretId: any; interpretExpectedId: any; testCase: any }): Promise<void> => {
    return Promise.all([
        interpretCheck({id: value.interpretId}),
        interpretCheck({id: value.interpretExpectedId}),
    ]).then(res => {
        if (res[0].state === "SUCCESS" && res[1].state === "SUCCESS") {
            leetCodeOutputChannel.show().clear().appendTime();
            if (res[0].run_success) {
                leetCodeOutputChannel
                    .appendLine("执行用时：" + res[0].status_runtime + "，消耗内存：" + res[0].status_memory)
                    .appendLine("输入：").appendLine(value.testCase)
                    .appendLine("输出：").appendLine(`${res[0].code_answer}`)
                    .appendLine("预期输出：").appendLine(`${res[0].expected_code_answer}`);
            } else {
                if (res[0].status_msg === "Compile Error") {
                    leetCodeOutputChannel.appendLine("编译错误")
                        .appendLine(res[0].full_compile_error ?? "");
                } else if (res[0].status_msg === "Runtime Error") {
                    leetCodeOutputChannel.appendLine("运行时错误")
                        .appendLine(res[0].full_runtime_error ?? "");
                } else if (res[0].status_msg === "Memory Limit Exceeded") {
                    leetCodeOutputChannel.appendLine("超出内存限制");
                } else if (res[0].status_msg === "Time Limit Exceeded") {
                    leetCodeOutputChannel.appendLine("超出时间限制");
                } else {
                    leetCodeOutputChannel.appendLine(JSON.stringify(res[0]));
                }
            }
            return;
        }
        return wait(200).then(() => check(value));
    });
};